package com.mengxuegu.workflow;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiTest04ProcessDefinition {

    @Autowired
    RepositoryService repositoryService;

    /**
     * 查询部署的流程定义数据 ACT_RE_PROCDEF
     * <p>
     * 需求：如果有多个相同流程定义标识key的流程时，只查询其最新版本
     */
    @Test
    public void getProcessDefinitionList() {
        // 1. 获取 ProcessDefinitionQuery 
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
        // 条件查询 
        query.processDefinitionNameLike("%请假%");
        // 有多个相同标识key的流程时，只查询其最新版本
        query.latestVersion();
        // 按流程定义key升序排列
        query.orderByProcessDefinitionKey().asc();
        // 当前查询第几页 
        int current = 1;
        // 每页显示多少条数据 
        int size = 5;
        // 当前页第1条数据下标 
        int firstResult = (current - 1) * size;
        // 开始分页查询
        List<ProcessDefinition> definitionList = query.listPage(firstResult, size);
        for (ProcessDefinition pd : definitionList) {
            System.out.print("流程部署ID：" + pd.getDeploymentId());
            System.out.print("，流程定义ID：" + pd.getId());
            System.out.print("，流程定义Key：" + pd.getKey());
            System.out.print("，流程定义名称：" + pd.getName());
            System.out.print("，流程定义版本号：" + pd.getVersion());
            System.out.println("，状态：" + (pd.isSuspended() ? "挂起(暂停)" : "激活(开启)"));
        }
        // 用于前端显示页面，总记录数
        long total = query.count();
        System.out.println("满足条件的流程定义总记录数：" + total);
    }

    /**
     * 通过流程定义id，挂起或激活流程定义
     *
     * 对应 act_re_procdef 表中的 SUSPENSION_STATE_ 字段，1是激活，2是挂起
     */
    @Test
    public void updateProcessDefinitionState() {
        // 流程定义ID
        String definitionId = "leaveProcess:2:b9227310-c8f4-11eb-acbf-aa2e2e85fc05";
        // 流程定义对象
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(definitionId)
                .singleResult();
        // 获取当前状态是否为：挂起
        boolean suspended = processDefinition.isSuspended();
        if (suspended) {
            // 如果状态是：挂起，将状态更新为：激活，
            // 参数1: 流程定义id；参数2：是否级联激活该流程定义下的流程实例；参考3：设置什么时间激活这个流程定义，如果 null 则立即激活
            repositoryService.activateProcessDefinitionById(definitionId, true, null);
        } else {
            // 如果状态是：激活，将状态更新为：挂起
            // 参数 (流程定义id，是否挂起，激活时间)
            repositoryService.suspendProcessDefinitionById(definitionId, true, null);
        }
    }

    /**
     * 导出/下载流程定义文件(.bpmn20.xml流程描述或.png图片资源)
     */
    @Test
    public void exportProcessDefinitionFile() throws Exception{
        // 流程定义ID
        String definitionId = "leaveProcess:2:b9227310-c8f4-11eb-acbf-aa2e2e85fc05";
        // 查询流程定义数据
        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(definitionId);
        // xml 文件名
        //String filename = processDefinition.getResourceName();
        // png 图片名
        String filename = processDefinition.getDiagramResourceName();
        // 获取对应文件输入流
        InputStream input = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), filename);
        // 创建输出流
        File file = new File("/Users/mengxuegu/" + filename);
        FileOutputStream output = new FileOutputStream(file);
        // 流拷贝
        IOUtils.copy(input, output);
        // 关闭流
        input.close();
        output.close();
        System.out.println("流程定义文件导出成功：" + filename);
    }

}
